// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	12/29/2013 9:10:08 PM				
// -----------------------------

#include "Vector2.h"
#include "CMath.h"

namespace Flow
{
	
	/* Constants */
	const Vector2 Vector2::Zero = Vector2(0.0f, 0.0f);
	const Vector2 Vector2::One = Vector2(1.0f, 1.0f);
	const Vector2 Vector2::UnitX = Vector2(1.0f, 0.0f);
	const Vector2 Vector2::UnitY = Vector2(0.0f, 1.0f);
	
	/* Constructors */
	Vector2::Vector2()
		: x(0.0f)
		, y(0.0f)
	{
	}
	
	Vector2::Vector2(Float X, Float Y)
		: x(X)
		, y(Y)
	{
	}
	
	Vector2::Vector2(const Vector2& refVector)
		: x(refVector.x)
		, y(refVector.y)
	{
	}
	
	Vector2& Vector2::operator=(const Vector2& refVector)
	{
		x = refVector.x;
		y = refVector.y;
		return (*this);
	}
	
	
	/* Comparison Operators */
	Bool Vector2::operator==(const Vector2& refVector) const
	{
		return (x == refVector.x) &&
			(y == refVector.y);
	}
	
	Bool Vector2::operator!=(const Vector2& refVector) const
	{
		return (x != refVector.x) ||
			(y != refVector.y);
	}
	
	Bool Vector2::operator<(const Vector2& refVector) const
	{
		return (x < refVector.x) &&
			(y < refVector.y);
	}
	
	Bool Vector2::operator>(const Vector2& refVector) const
	{
		return (x > refVector.x) &&
			(y > refVector.y);
	}
	
	Bool Vector2::operator<=(const Vector2& refVector) const
	{
		return (x <= refVector.x) &&
			(y <= refVector.y);
	}
	
	Bool Vector2::operator>=(const Vector2& refVector) const
	{
		return (x >= refVector.x) &&
			(y >= refVector.y);
	}
	
	
	/* Mathematical In-Place operators */
	Vector2& Vector2::operator+=(const Vector2& refVector)
	{
		x += refVector.x;
		y += refVector.y;
		return (*this);
	}
	
	Vector2& Vector2::operator-=(const Vector2& refVector)
	{
		x -= refVector.x;
		y -= refVector.y;
		return (*this);
	}
	
	Vector2& Vector2::operator*=(Float fScalar)
	{
		x *= fScalar;
		y *= fScalar;
		return (*this);
	}
	
	Vector2& Vector2::operator/=(Float fScalar)
	{
		x /= fScalar;
		y /= fScalar;
		return (*this);
	}
	
	
	/* Mathematical Out-Of-Place Operators */
	Vector2 Vector2::operator+(const Vector2& refVector) const
	{
		Vector2 tmp(*this);
		tmp += refVector;
		return tmp;
	}
	
	Vector2 Vector2::operator-(const Vector2& refVector) const
	{
		Vector2 tmp(*this);
		tmp -= refVector;
		return tmp;
	}
	
	Vector2 Vector2::operator-() const
	{
		return Vector2(-x, -y);
	}
	
	Vector2 Vector2::operator*(Float fScalar) const
	{
		Vector2 tmp(*this);
		tmp *= fScalar;
		return tmp;
	}
	
	Vector2 Vector2::operator/(Float fScalar) const
	{
		Vector2 tmp(*this);
		tmp /= fScalar;
		return tmp;
	}
	
	
	/* Mathematical Friend Operators */
	Vector2 operator*(Float fScalar, const Vector2& refVector)
	{
		return (refVector * fScalar);
	}
	
	
	/* Methods */
	Float Vector2::Length() const
	{
		return Math::Sqrt(x*x + y*y);
	}
	
	Vector2 Vector2::Normalized() const
	{
		return ((*this) / this->Length());
	}
	
	Float Vector2::DotProduct(const Vector2& refVector) const
	{
		return (x * refVector.x) + (y * refVector.y);
	}
	void Vector2::AsArray(Float arr[2]) const
	{
		arr[0] = x;
		arr[1] = y;
	}
	Vector2 Vector2::Lerp(const Vector2& other, Float alpha) const
	{
		return Vector2(Math::Lerp(x, other.x, alpha),
			Math::Lerp(y, other.y, alpha));
	}
}